using System;
using System.Collections.Generic;
using System.Data;
using System.Workflow.ComponentModel;
using System.Workflow.Activities;
using Microsoft.Crm.Workflow;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using System.IO;
using System.Web;
using System.Xml;
using System.Linq;
using System.Xml.Linq;
using MSA.Integration;
using Microsoft.Crm.Sdk.Query;

namespace MSA.SocialNetworking
{
    [CrmWorkflowActivity("Get Updates", "MSA Social Networking")]
    public partial class GetUpdates : Activity
    {

        // Override this method with our custom logic
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            //Get the Guid from the Workflow
            IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
            IWorkflowContext ctx = contextService.Context;
            ICrmService crmService = ctx.CreateCrmService();
            string recordId = ctx.PrimaryEntityId.ToString();
            string timestamp = DateTime.UtcNow.ToString("yyyyMMddhhmmss");
            string _xslt = string.Empty;

            DynamicEntity dEntity = ctx.PrimaryEntityImage;
            string msa_snuserid = ((Lookup)dEntity.Properties["msa_twitteruseraccountid"]).Value.ToString();
            dEntity = null;
            //Get Integration Configuration from CRM i.e. XSLT transform
            ColumnSet cset = new ColumnSet(new String[] { "msa_integrationconfigurationid", "msa_configstring" });
            try
            {
                DynamicEntity dataset = inbound.CrmSearch("msa_integrationconfiguration", "msa_name", "Twitter.GetUpdates", cset, crmService);
                _xslt = dataset["msa_configstring"].ToString();
            }
            catch (Exception e)
            {
                this.ReturnStatus = LastId;
                return base.Execute(executionContext);
            }
            //end xslt

            _xslt = string.Format(_xslt, msa_snuserid);
            Boolean debugflag;

            if (Debug == "true")
            {
                debugflag = true;
            }
            else
            {
                debugflag = false;
            }

            XDocument xDoc = new XDocument();
            string since_id = string.Empty;
            var sUpdates = new List<String>();
            msa_twitter twGetUpdates = new msa_twitter();

            if (twGetUpdates.SetCredentials(UserName, Password))
            {
                string returnXml = twGetUpdates.GetUpdates(LastId);
                xDoc = XDocument.Parse(returnXml);
                string sEntity = string.Empty;
                string sSource = string.Empty;
                string sSourceObject = string.Empty;
                string sAttributeType = string.Empty;
                string sAttributeName = string.Empty;
                Guid sCrmGuid = Guid.Empty;

                //Insert Pagination here
                try
                {
                    since_id = xDoc.Root.Elements("status").First().Element("id").Value;
                    xDoc = XDocument.Parse(msa_transformation.Transform(returnXml, _xslt, debugflag));
                    sSource = xDoc.Root.Attribute("source").Value;
                    sEntity = xDoc.Root.Attribute("crm_entity").Value;
                    sSourceObject = xDoc.Root.Attribute("source_object").Value;
                    Guid lookupGuid = Guid.Empty;
                    var query = from p in xDoc.Root.Elements("record")
                                select p;
                    //Get the records from the xml and iterate through them
                    foreach (var x in query)
                    {
                        foreach (var a in x.Elements())
                        {
                            if (a.Name == "lookup")
                            {
                                lookupGuid = inbound.CrmGuidLookup(a.Attribute("entity_name").Value, a.Attribute("search").Value, a.Attribute("search_key").Value, a, crmService);
                            }
                        }
                    }
                    xDoc = null;
                    query = null;
                    //
                    this.ReturnStatus = since_id;
                }
                catch (NullReferenceException e)
                {
                    //status element does not contain the right attributes
                    since_id = LastId;
                }
                catch (InvalidOperationException)
                {
                //The resultset is null
					since_id = LastId;
                }
            }
            else
            {
                since_id = LastId;
            }
            //garbage disposal
            _xslt = null;
            xDoc = null;
            this.ReturnStatus = since_id;
            return base.Execute(executionContext);
        }

        // Allow the user to set the Username that authenticates to Twitter 
        public static DependencyProperty UserNameProperty = DependencyProperty.Register("UserName", typeof(string), typeof(GetUpdates));
        [CrmInput("UserName")]
        public string UserName
        {
            get { return (string)base.GetValue(UserNameProperty); }
            set { base.SetValue(UserNameProperty, value); }
        }

        // Allow the user to set the Password 
        public static DependencyProperty PasswordProperty = DependencyProperty.Register("Password", typeof(string), typeof(GetUpdates));
        [CrmInput("Password")]
        public string Password
        {
            get { return (string)base.GetValue(PasswordProperty); }
            set { base.SetValue(PasswordProperty, value); }
        }

        public static DependencyProperty LastIdProperty = DependencyProperty.Register("LastId", typeof(string), typeof(GetUpdates));
        [CrmInput("Last Id")]
        public string LastId
        {
            get { return (string)base.GetValue(LastIdProperty); }
            set { base.SetValue(LastIdProperty, value); }
        }

        public static DependencyProperty DebugProperty = DependencyProperty.Register("Debug", typeof(string), typeof(GetUpdates));
        [CrmInput("Debug")]
        public string Debug
        {
            get { return (string)base.GetValue(DebugProperty); }
            set { base.SetValue(DebugProperty, value); }
        }

        // Returns the formatted email MailTo Url to the workflow rule for use  
        public static DependencyProperty ReturnStatusProperty = DependencyProperty.Register("ReturnStatus", typeof(string), typeof(GetUpdates));
        [CrmOutput("ReturnStatus")]
        public string ReturnStatus
        {
            get { return (string)base.GetValue(ReturnStatusProperty); }
            set { base.SetValue(ReturnStatusProperty, value); }
        }
    }
}